TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import type { Metadata } from 'next';2import Link from 'next/link';3import { notFound } from 'next/navigation';4import { PageHeader } from '@/components/ui/page-header';5import { Stat } from '@/components/ui/primitives';6import { AssetBrowser } from '@/components/market/asset-browser';7import { Suspense } from 'react';8import { Skeleton } from '@/components/ui/primitives';9import { getBrandStats } from '@/lib/queries/markets';10import { catName } from '@/lib/taxonomy';11import { fmtMoney, fmtNum } from '@/lib/format';12import type { SP } from '@/lib/search-params';1314export const revalidate = 300;1516export async function generateMetadata({ params }: { params: Promise<{ brand: string }> }): Promise<Metadata> {17 const { brand } = await params;18 const name = decodeURIComponent(brand);19 return { title: `${name} collectibles`, description: `${name}: tracked collectible assets, valuations, sales and listings on RareIndex.` };20}2122export default async function BrandPage({ params, searchParams }: { params: Promise<{ brand: string }>; searchParams: Promise<SP> }) {23 const { brand } = await params;24 const sp = await searchParams;25 const name = decodeURIComponent(brand);26 const stats = await getBrandStats(name);27 if (!stats) notFound();28 return (29 <div>30 <PageHeader31 crumbs={[{ label: 'Markets', href: '/markets' }, { label: stats.brand }]}32 title={stats.brand}33 description="Brand view across every category where this brand appears."34 meta={stats.categories.map((c) => (35 <Link key={c} href={`/markets/${c}`} className="rounded-sm bg-inset px-1.5 py-0.5 hover:text-fg">36 {catName(c)}37 </Link>38 ))}39 />40 <section className="grid grid-cols-2 gap-px overflow-hidden rounded-md border border-border bg-border sm:grid-cols-3 lg:grid-cols-6">41 {[42 ['Tracked assets', fmtNum(stats.assets)],43 ['With valuation', fmtNum(stats.priced)],44 ['Sales', fmtNum(stats.sales)],45 ['Active listings', fmtNum(stats.listings)],46 ['Median RIV', stats.medianRivUsd != null ? fmtMoney(stats.medianRivUsd) : '—'],47 ['Top RIV', stats.maxRivUsd != null ? fmtMoney(stats.maxRivUsd) : '—'],48 ].map(([k, v]) => (49 <div key={k} className="bg-elevated px-3 py-2.5">50 <Stat label={k} value={v} />51 </div>52 ))}53 </section>54 <div className="mt-4">55 <Suspense fallback={<Skeleton className="h-96" />}>56 <AssetBrowser scope={{ brand: name }} sp={sp} basePath={`/brand/${brand}`} title={`${stats.brand} assets`} pageSize={60} />57 </Suspense>58 </div>59 </div>60 );61}62